package fr.mywiki.business.entry.meta.datatype;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;

import fr.mywiki.business.entry.meta.DataType;
import fr.mywiki.business.entry.meta.datatype.number.IntNumber;
import fr.mywiki.business.entry.meta.datatype.number.RealNumber;
import fr.mywiki.business.entry.meta.datatype.text.SimpleText;
import fr.mywiki.business.entry.meta.datatype.text.WikiText;
import fr.mywiki.business.resources.ResourceManager;

/** Several methods for the datatypes management. */
public class DataTypeManager {
	/**
	 * The available dataTypes, a <code>Hashtable</code> of <code>Locale</code>
	 * objects linked to <code>HashTable</code> objects where id (linked to the
	 * intern type name) and name (linked to the displayed type name) are the two
	 * keys.
	 */
	private static Hashtable dataTypes;
	
	/** A list containing the DataType objects names. */
	private static List dataTypesNames;
	
	/**
	 * Eventually loads and returns the available data types.
	 * 
	 * @param locale
	 *          the locale of the user
	 */
	public static List getDataTypes(Locale locale) {
		if (dataTypes == null || dataTypes.get(locale) == null)
			loadDataTypes(locale);
		return (List) dataTypes.get(locale);
	}
	
	/**
	 * Builds a part of the <code>dataTypes</code> object, the one linked to the
	 * locale given in parameter. dataTypes is used to display all the data types
	 * available.
	 * 
	 * TODO reintegrer Choice et EntryLink
	 */
	private static void loadDataTypes(Locale locale) {
		ArrayList list = new ArrayList();
		
		Hashtable table = new Hashtable();
		table.put("id", SimpleText.TYPE_NAME);
		table.put("name", ResourceManager.getMessage(SimpleText.TYPE_BUNDLE_KEY,
				locale));
		list.add(table);

		table = new Hashtable();
		table.put("id", WikiText.TYPE_NAME);
		table.put("name", ResourceManager.getMessage(WikiText.TYPE_BUNDLE_KEY,
				locale));
		list.add(table);

//		table = new Hashtable();
//		table.put("id", Choice.TYPE_NAME);
//		table.put("name", ResourceManager
//				.getMessage(Choice.TYPE_BUNDLE_KEY, locale));
//		list.add(table);

		table = new Hashtable();
		table.put("id", DateProperty.TYPE_NAME);
		table.put("name", ResourceManager.getMessage(DateProperty.TYPE_BUNDLE_KEY,
				locale));
		list.add(table);

//		table = new Hashtable();
//		table.put("id", EntryLink.TYPE_NAME);
//		table.put("name", ResourceManager.getMessage(EntryLink.TYPE_BUNDLE_KEY,
//				locale));
//		list.add(table);

		table = new Hashtable();
		table.put("id", IntNumber.TYPE_NAME);
		table.put("name", ResourceManager.getMessage(IntNumber.TYPE_BUNDLE_KEY,
				locale));
		list.add(table);

		table = new Hashtable();
		table.put("id", RealNumber.TYPE_NAME);
		table.put("name", ResourceManager.getMessage(RealNumber.TYPE_BUNDLE_KEY,
				locale));
		list.add(table);
		
		if (dataTypes == null)
			dataTypes = new Hashtable();
		dataTypes.put(locale, list);
	}
	
	private static void loadDataTypesNames() {
		dataTypesNames = new ArrayList();
		
		dataTypesNames.add(SimpleText.TYPE_NAME);
		dataTypesNames.add(WikiText.TYPE_NAME);
		dataTypesNames.add(Choice.TYPE_NAME);
		dataTypesNames.add(DateProperty.TYPE_NAME);
		dataTypesNames.add(EntryLink.TYPE_NAME);
		dataTypesNames.add(IntNumber.TYPE_NAME);
		dataTypesNames.add(RealNumber.TYPE_NAME);
	}
	
	/**
	 * Returns the name of the data type whose index is given in parameter.
	 * 
	 * @param index
	 *          an int number.
	 * @return a <code>String</code> object.
	 */
	public static String getDataTypeName(int index) {
		if(dataTypesNames == null)
			loadDataTypesNames();
		return (String) dataTypesNames.get(index);
	}
	
	/**
	 * Creates and returns a <code>DataType</code> object from its name given in
	 * parameter.
	 * 
	 * @param name
	 *          the name of the data type.
	 * @return an empty <code>DataType</code> object.
	 */
	public static DataType createDataType(String name) {
		if (dataTypesNames == null)
			loadDataTypesNames();
		
		return createDataType(dataTypesNames.indexOf(name));
	}
	
	/**
	 * Creates and returns a <code>DataType</code> object from its index given in
	 * parameter, index which corresponds to its order inside <code>dataTypesNames</code>.
	 * 
	 * @param index
	 *          an int number.
	 * @return an empty <code>DataType</code> object.
	 */
	public static DataType createDataType(int index) {
		switch (index) {
		case 0:
			return new SimpleText();
		case 1:
			return new WikiText();
		case 2:
			return new Choice();
		case 3:
			return new DateProperty();
		case 4:
			return new EntryLink();
		case 5:
			return new IntNumber();
		case 6:
			return new RealNumber();
		}
		return null;
	}
}
